/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.moco.launcher.wifi;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.AttributeSet;

import android.util.Log;

import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.moco.launcher.R;
import com.moco.launcher.activity.MainActivity;
import com.moco.launcher.dialog.WaitDialog;
import com.oazon.common.util.ReflectionUtil;
import com.oazon.common.Logger;

/**
 * Two types of UI are provided here.
 *
 * The first is for "usual Settings", appearing as any other Setup fragment.
 *
 * The second is for Setup Wizard, with a simplified interface that hides the action bar
 * and menus.
 */
@SuppressLint("NewApi") 
public class NewWifiSettings extends Fragment
        implements DialogInterface.OnClickListener,OnItemClickListener,OnClickListener  {
    private static final String TAG = "NewWifiSettings";
    
    private static final int MENU_ID_WPS_PBC = Menu.FIRST;
    private static final int MENU_ID_WPS_PIN = Menu.FIRST + 1;
    private static final int MENU_ID_P2P = Menu.FIRST + 2;
    private static final int MENU_ID_ADD_NETWORK = Menu.FIRST + 3;
    private static final int MENU_ID_ADVANCED = Menu.FIRST + 4;
    private static final int MENU_ID_SCAN = Menu.FIRST + 5;
    private static final int MENU_ID_CONNECT = Menu.FIRST + 6;
    private static final int MENU_ID_FORGET = Menu.FIRST + 7;
    private static final int MENU_ID_MODIFY = Menu.FIRST + 8;
    private static final int WIFI_DIALOG_ID = 1;
    private static final int WPS_PBC_DIALOG_ID = 2;
    private static final int WPS_PIN_DIALOG_ID = 3;
    private static final int WIFI_SKIPPED_DIALOG_ID = 4;
    private static final int WIFI_AND_MOBILE_SKIPPED_DIALOG_ID = 5;

    // Combo scans can take 5-6s to complete - set to 10s.
    private static final int WIFI_RESCAN_INTERVAL_MS = 10 * 1000;

    // Instance state keys
    private static final String SAVE_DIALOG_EDIT_MODE = "edit_mode";
    private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state";

    // Activity result when pressing the Skip button
    private static final int RESULT_SKIP = Activity.RESULT_FIRST_USER;
    
    // this boolean extra specifies whether to disable the Next button when not connected
    private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect";

    // this boolean extra specifies whether to auto finish when connection is established
    private static final String EXTRA_AUTO_FINISH_ON_CONNECT = "wifi_auto_finish_on_connect";

    // this boolean extra shows a custom button that we can control
    protected static final String EXTRA_SHOW_CUSTOM_BUTTON = "wifi_show_custom_button";

    // show a text regarding data charges when wifi connection is required during setup wizard
    protected static final String EXTRA_SHOW_WIFI_REQUIRED_INFO = "wifi_show_wifi_required_info";

    private IntentFilter mFilter;
    private BroadcastReceiver mReceiver;
    private Scanner mScanner;
    private WifiManager mWifiManager;
    private Activity mActivity = null;  
    private ActionListener mConnectListener;
    private boolean mP2pSupported;
    private WifiEnabler mWifiEnabler;
    // An access point being editted is stored here.
    private AccessPoint mSelectedAccessPoint;
    private DetailedState mLastState;
    private WifiInfo mLastInfo;
    private final AtomicBoolean mConnected = new AtomicBoolean(false);
    private WifiDialog mDialog;
    private TextView mEmptyView;

    // this boolean extra is set if we are being invoked by the Setup Wizard
    private static final String EXTRA_IS_FIRST_RUN = "firstRun";

    // should Next button only be enabled when we have a connection?
    private boolean mEnableNextOnConnection;

    // should activity finish once we have a connection?
    private boolean mAutoFinishOnConnection;

    // Save the dialog details
    private boolean mDlgEdit;
    private AccessPoint mDlgAccessPoint;
    private Bundle mAccessPointSavedState;

    // the action bar uses a different set of controls for Setup Wizard
    private boolean mSetupWizardMode;
    
    private List<AccessPoint> mWifis;
    private WifiItemAdapter mWifiItemAdapter;
    private View mRootView;
    private ListView mLstViewWifi;
    private ConnectImpl connectImpl;
    private TextView mTxtViewScanner;
    private ImageView mImgViewExit;
    private String mLastConnectApSSID;
    private boolean IS_SCAN_CLICK=false;
    
    /* End of "used in Wifi Setup context" */
    private WaitDialog dialog = null;

	public NewWifiSettings(ConnectImpl connectImpl) {
    		this.connectImpl = connectImpl;
    		
        mFilter = new IntentFilter();
        mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION);
        mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
        mFilter.addAction(ReflectionUtil.CONFIGURED_NETWORKS_CHANGED_ACTION);
        mFilter.addAction(ReflectionUtil.LINK_CONFIGURATION_CHANGED_ACTION);
        mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);

        mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                handleEvent(context, intent);
            }
        };

        mScanner = new Scanner();
    }

    @Override
    public void onCreate(Bundle icicle) {
        // Set this flag early, as it's needed by getHelpResource(), which is called by super
        mSetupWizardMode = getActivity().getIntent().getBooleanExtra(EXTRA_IS_FIRST_RUN, false);
        
        super.onCreate(icicle);
    }

    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
	    	mActivity = getActivity();
	    	
	    if(dialog == null)
	    		dialog = WaitDialog.createDialog(mActivity);
	
	    	mWifis = new ArrayList<AccessPoint>();
	    	mWifiItemAdapter = new WifiItemAdapter(getActivity());
	    	mRootView = inflater.inflate(R.layout.wifi_list_layout, container, false);
	    	
	    	mLstViewWifi = (ListView)mRootView.findViewById(R.id.wifi_listview);
	    	mEmptyView = (TextView) mRootView.findViewById(android.R.id.empty);
	    	mTxtViewScanner = (TextView) mRootView.findViewById(R.id.wifi_scanner_txt);
	    	mImgViewExit = (ImageView)mRootView.findViewById(R.id.wifi_list_exit);
	    	
	    	mLstViewWifi.setOnItemClickListener(this);
	    	mTxtViewScanner.setOnClickListener(this);
	    	mImgViewExit.setOnClickListener(this);
    	
        if (mSetupWizardMode) {
            Intent intent = getActivity().getIntent();
            if (intent.getBooleanExtra(EXTRA_SHOW_CUSTOM_BUTTON, false))
            		Logger.d(TAG, "get Intent with show custom button");

            if (intent.getBooleanExtra(EXTRA_SHOW_WIFI_REQUIRED_INFO, false))
            		mRootView.findViewById(R.id.wifi_required_info).setVisibility(View.VISIBLE);
        }
        return mRootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mP2pSupported = getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT);
        mWifiManager = (WifiManager) getActivity().getSystemService(Context.WIFI_SERVICE);
        
        if(mWifiManager.isWifiEnabled()) {
        		if(mWifiManager.getWifiState() != WifiManager.WIFI_STATE_ENABLED) {
        			Toast.makeText(mActivity, "wifi 不可用", 1).show();
        			connectImpl.exit(ConnectImpl.LIST);
        		}
        }

        mConnectListener = new ActionListener() {
                       @Override
                       public void onSuccess() {
                    	       Logger.d(TAG, "CONNECT success");
                       }
                       
                       @Override
                       public void onFailure(int reason) {
                    	       Logger.d(TAG, "CONNECT fail");
                           Activity activity = getActivity();
                           if (activity == null) 
                        	   		return;
                           Toast.makeText(activity, R.string.wifi_failed_connect_message,Toast.LENGTH_SHORT).show();
                       }
                   };


        if (savedInstanceState != null && 
        		savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {
            mDlgEdit = savedInstanceState.getBoolean(SAVE_DIALOG_EDIT_MODE);
            mAccessPointSavedState = savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);
        }

        final Activity activity = getActivity();
        final Intent intent = activity.getIntent();

        // first if we're supposed to finish once we have a connection
        mAutoFinishOnConnection = intent.getBooleanExtra(EXTRA_AUTO_FINISH_ON_CONNECT, false);
        Logger.i(TAG, "mAutoFinishOnConnection==="+mAutoFinishOnConnection);
        if (mAutoFinishOnConnection) {
            final ConnectivityManager connectivity = (ConnectivityManager)
                    activity.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (connectivity != null && 
            		connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
                activity.setResult(Activity.RESULT_OK);
                activity.finish();
                return;
            }
        }

        // if we're supposed to enable/disable the Next button based on our current connection
        // state, start it off in the right state
        mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);

        // On/off switch is hidden for Setup Wizard
        if (!mSetupWizardMode) {
            Switch actionBarSwitch = new Switch(activity);

            if (activity instanceof PreferenceActivity) {
                PreferenceActivity preferenceActivity = (PreferenceActivity) activity;
                if (preferenceActivity.onIsHidingHeaders() || !preferenceActivity.onIsMultiPane()) {
                    final int padding = activity.getResources().getDimensionPixelSize(
                            R.dimen.action_bar_switch_padding);
                    actionBarSwitch.setPaddingRelative(0, 0, padding, 0);
                    activity.getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
                            ActionBar.DISPLAY_SHOW_CUSTOM);
                    activity.getActionBar().setCustomView(actionBarSwitch, new ActionBar.LayoutParams(
                            ActionBar.LayoutParams.WRAP_CONTENT,
                            ActionBar.LayoutParams.WRAP_CONTENT,
                            Gravity.CENTER_VERTICAL | Gravity.END));
                }
            }

            mWifiEnabler = new WifiEnabler(activity, actionBarSwitch);
        }

        setHasOptionsMenu(true);
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mWifiEnabler != null)
            mWifiEnabler.resume();
        
        getActivity().registerReceiver(mReceiver, mFilter);
        updateAccessPoints();
    }
    
    private void updatePadding(){
    		//设置padding
    		float sideMargin = getResources().getFraction(R.dimen.setup_border_width, 1, 1);
    		Logger.d(TAG, "enter onCreateView--sideMargin is:" + sideMargin);
        int bottom = getResources().getDimensionPixelSize(R.dimen.setup_margin_bottom);
        int parentWidth = mRootView.getMeasuredWidth();
        mRootView.setPaddingRelative((int)(parentWidth * sideMargin), 0, (int) (parentWidth * sideMargin), bottom);
    }

    @Override
    public void onPause() {
        super.onPause();
        
        Logger.d(TAG, "enter onPause--");
        if (mWifiEnabler != null)
            mWifiEnabler.pause();

        getActivity().unregisterReceiver(mReceiver);
        mScanner.pause();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        
        Logger.d(TAG, "enter onSaveInstanceState--");
        // If the dialog is showing, save its state.
        if (mDialog != null && mDialog.isShowing()) {
            outState.putBoolean(SAVE_DIALOG_EDIT_MODE, mDlgEdit);
            if (mDlgAccessPoint == null) 
            		return;
            
            mAccessPointSavedState = new Bundle();
            mDlgAccessPoint.saveWifiState(mAccessPointSavedState);
            outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState);
        }
    }
    
    public void connectApByConfig() {
	    	try {
	    		reconnectAp();
	    	} catch (Exception e) {
			e.printStackTrace();
	    	}   	
    }

    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
        if (!(preference instanceof AccessPoint)) 
        		return true;
        
        mSelectedAccessPoint = (AccessPoint) preference;
        /** Bypass dialog for unsecured, unsaved networks */
        //for hide
        if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
            mSelectedAccessPoint.networkId == ReflectionUtil.INVALID_NETWORK_ID) {
            mSelectedAccessPoint.generateOpenNetworkConfig();
            Logger.d(TAG, "connectApByConfig ");
            connectApByConfig();
        } else {
        		Logger.d(TAG, "show dialog");
            showDialog(mSelectedAccessPoint, false);
        }
        
        return true;
    }

    private void showDialog(AccessPoint accessPoint, boolean edit) {
        if (mDialog != null) {
            getActivity().dismissDialog(WIFI_DIALOG_ID);
            mDialog = null;
        }

        // Save the access point and edit mode
        mDlgAccessPoint = accessPoint;
        mDlgEdit = edit;

        getActivity().showDialog(WIFI_DIALOG_ID);
    }

    public Dialog onCreateDialog(int dialogId) {
    		WifiDialog dialog = null;
        switch (dialogId) {
            case WIFI_DIALOG_ID:
                AccessPoint ap = mDlgAccessPoint; // For manual launch
                if (ap == null) { // For re-launch from saved state
                		Logger.d(TAG, "AP Is null");
                    if (mAccessPointSavedState != null) {
                        ap = new AccessPoint(getActivity(), mAccessPointSavedState);
                        // For repeated orientation changes
                        mDlgAccessPoint = ap;
                        // Reset the saved access point data
                        mAccessPointSavedState = null;
                    }
                }
                Logger.d(TAG, "AP Is not null");
                Logger.d(TAG, "ssid=" + ap.bssid);                
                // If it's still null, fine, it's for Add Network
                mSelectedAccessPoint = ap;
                mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);
                dialog = mDialog;
                break;
              default:
            	  	break;
        	}
        return dialog;
    }

    /**
     * Shows the latest access points available with supplimental information like
     * the strength of network and the security for it.
     */
    private void updateAccessPoints() {
        if (getActivity() == null) 
        		return;
        
        final int wifiState = mWifiManager.getWifiState();

        switch (wifiState) {
            case WifiManager.WIFI_STATE_ENABLED:
            	//where 
                // AccessPoints are automatically sorted with TreeSet.
                final Collection<AccessPoint> accessPoints = constructAccessPoints();
                mWifis.clear();
                if(accessPoints.size() == 0)
                    addMessagePreference(R.string.wifi_empty_list_wifi_on);
                
                for (AccessPoint accessPoint : accessPoints) {
                		mWifis.add(accessPoint);
                }

                mWifiItemAdapter.setWifiListData(mWifis);
                mLstViewWifi.setAdapter(mWifiItemAdapter);
                if(IS_SCAN_CLICK){
                handler.sendEmptyMessageDelayed(9001, 0);
                IS_SCAN_CLICK=false;
                }
                break;
            
            case WifiManager.WIFI_STATE_ENABLING:
            		mWifis.clear();
            		mWifiItemAdapter.notifyDataSetChanged();
                break;

            case WifiManager.WIFI_STATE_DISABLING:
                addMessagePreference(R.string.wifi_stopping);
                break;

            case WifiManager.WIFI_STATE_DISABLED:
            
                setOffMessage();
                break;
        }
    }

    private void setOffMessage() {
        if (mEmptyView == null)
        		return;
        
        mEmptyView.setText(R.string.wifi_empty_list_wifi_off);
    }

    private void addMessagePreference(int messageId) {
        if (mEmptyView == null)
        		return;
        
        	mEmptyView.setText(messageId);
    }

    /** Returns sorted list of access points */
    private List<AccessPoint> constructAccessPoints() {
        ArrayList<AccessPoint> accessPoints = new ArrayList<AccessPoint>();
        /** Lookup table to more quickly update AccessPoints by only considering objects with the
         * correct SSID.  Maps SSID -> List of AccessPoints with the given SSID.  */
        Multimap<String, AccessPoint> apMap = new Multimap<String, AccessPoint>();

        final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
        if (configs != null) {
            for (WifiConfiguration config : configs) {
                AccessPoint accessPoint = new AccessPoint(getActivity(), config);
                accessPoint.update(mLastInfo, mLastState);
                accessPoints.add(accessPoint);
                apMap.put(accessPoint.ssid, accessPoint);
            }
        }

        final List<ScanResult> results = mWifiManager.getScanResults();
        if (results != null) {
            for (ScanResult result : results) {
                // Ignore hidden and ad-hoc networks.
                if (result.SSID == null || 
                		result.SSID.length() == 0 ||
                    result.capabilities.contains("[IBSS]")) {
                    continue;
                }

                boolean found = false;
                for (AccessPoint accessPoint : apMap.getAll(result.SSID)) {
                    if (accessPoint.update(result))
                        found = true;
                }
                
                if (!found) {
                    AccessPoint accessPoint = new AccessPoint(getActivity(), result);
                    accessPoints.add(accessPoint);
                    apMap.put(accessPoint.ssid, accessPoint);
                }
            }
        }

        // Pre-sort accessPoints to speed preference insertion
        Collections.sort(accessPoints);
        return accessPoints;
    }

    /** A restricted multimap for use in constructAccessPoints */
    private class Multimap<K,V> {
        private final HashMap<K,List<V>> store = new HashMap<K,List<V>>();
        /** retrieve a non-null list of values with key K */
        List<V> getAll(K key) {
            List<V> values = store.get(key);
            return values != null ? values : Collections.<V>emptyList();
        }

        void put(K key, V val) {
            List<V> curVals = store.get(key);
            if (curVals == null) {
                curVals = new ArrayList<V>(3);
                store.put(key, curVals);
            }
            curVals.add(val);
        }
    }

	private void handleEvent(Context context, Intent intent) {
		String action = intent.getAction();
	  //  int reasonForDisConnect=	mSelectedAccessPoint.reasonForDisConnect;
	
		Logger.e(TAG, "action===="+action);
		if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
			  Logger.d(TAG, "CONNECTIVITY_ACTION");
              ConnectivityManager connectMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
              NetworkInfo ni = connectMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
              //WIFI是否连接成功
              if (ni.isConnected() ){
            		Logger.d(TAG, "WIFI成功连接了");
              }
              else{
            		Logger.d(TAG, "WIFI连接异常");
              }
            	  
		}

		if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
			

			//Log.e("test ples del",currentLastInfo.getBSSID()+currentLastInfo.get );
			updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
			Logger.d(TAG, "WIFI_STATE_CHANGED_ACTION");
		} else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) || 
				ReflectionUtil.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) || 
				ReflectionUtil.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) {
			 Logger.d(TAG, "SCAN_RESULTS_AVAILABLE_ACTION");
			updateAccessPoints();
		} else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) {
			// Ignore supplicant state changes when network is connected
			// TODO: we should deprecate SUPPLICANT_STATE_CHANGED_ACTION and
			// introduce a broadcast that combines the supplicant and network
			// network state change events so the apps dont have to worry about
			// ignoring supplicant state change when network is connected
			// to get more fine grained information.
			 Logger.d(TAG, "SUPPLICANT_STATE_CHANGED_ACTION");
			SupplicantState state = (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
			Method isHandshakeState = null;
			try {
				isHandshakeState = SupplicantState.class.getMethod("isHandshakeState", SupplicantState.class);
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			}
			
            boolean bIsState = false;
			try {
				bIsState = (Boolean) isHandshakeState.invoke(SupplicantState.class, state);
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
            if (!mConnected.get()&&bIsState) {
                updateConnectionState(WifiInfo.getDetailedStateOf(state));
             } else {
                 // During a connect, we may have the supplicant
                 // state change affect the detailed network state.
                 // Make sure a lost connection is updated as well.
                 updateConnectionState(null);
             }
        } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
        	Logger.d(TAG, "NETWORK_STATE_CHANGED_ACTION");
            NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
            WifiInfo currentLastInfo = mWifiManager.getConnectionInfo();
    			String mCurrentSSID = currentLastInfo.getSSID();
    			mCurrentSSID = mCurrentSSID.substring(1, mCurrentSSID.length()-1);
			if(mCurrentSSID!=null && 
			   mSelectedAccessPoint !=null && 
			   mCurrentSSID.equals(mSelectedAccessPoint.ssid)) {
				if(!mCurrentSSID.equals(mLastConnectApSSID)) {//不能重复提醒
					if(dialog !=null && dialog.isShowing()){
						dialog.dismiss();
						handler.removeMessages(9002);
					}
				
					if(info.isConnected()){
					Toast.makeText(mActivity, "连接成功", 1).show();
					   Activity activity = getActivity();
		                if (activity != null) {
		                    activity.setResult(Activity.RESULT_OK);
		                    activity.finish();
		                }}
					mLastConnectApSSID = mCurrentSSID;
				}
			}
    		
            mConnected.set(info.isConnected());
            changeNextButtonState(info.isConnected());
            updateAccessPoints();
            updateConnectionState(info.getDetailedState());
            /*- if (mAutoFinishOnConnection && info.isConnected()) 

            		解决开机后，wifi状态还未准备好，app跳转到wifi连接界面，待WiFi连接成功后，自动跳转至播放歌曲界面(MainActivity.getInstance().FIRST_TIME_START_WIFI==0x146)*/
            if (mAutoFinishOnConnection && info.isConnected()) {

                Activity activity = getActivity();
                if (activity != null) {
                    activity.setResult(Activity.RESULT_OK);
                    activity.finish();
                }
                return;
            }
        } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
        	Logger.d(TAG, "RSSI_CHANGED_ACTION");
            updateConnectionState(null);
        }
    }

    private void updateConnectionState(DetailedState state) {
        /* sticky broadcasts can call this when wifi is disabled */
        if (!mWifiManager.isWifiEnabled()) {
            mScanner.pause();
            return;
        }

        if (state == DetailedState.OBTAINING_IPADDR)
            mScanner.pause();
        else
            mScanner.resume();

        mLastInfo = mWifiManager.getConnectionInfo();
        if (state != null)
            mLastState = state;

        for (int i = mLstViewWifi.getCount() - 1; i >= 0; --i) {
            // Maybe there's a WifiConfigPreference
            AccessPoint preference = (AccessPoint)mLstViewWifi.getItemAtPosition(i);
            if (preference instanceof AccessPoint) {
                final AccessPoint ap = (AccessPoint) preference;
                ap.update(mLastInfo, mLastState);
            }
        }
    }

    private void updateWifiState(int state) {
        Activity activity = getActivity();
        if (activity != null)
            activity.invalidateOptionsMenu();
        Logger.i(TAG, "state=="+state);
        switch (state) {
            case WifiManager.WIFI_STATE_ENABLED:
            	  Logger.i(TAG, "WifiManager.WIFI_STATE_ENABLED");
                mScanner.resume();
                return; // not break, to avoid the call to pause() below

            case WifiManager.WIFI_STATE_ENABLING:
            	 Logger.i(TAG, "WifiManager.WIFI_STATE_ENABLED");
                addMessagePreference(R.string.wifi_starting);
                break;

            case WifiManager.WIFI_STATE_DISABLED:
            	 Logger.i(TAG, "WifiManager.WIFI_STATE_ENABLED");
            	Logger.e(TAG, "WIFI_STATE_DISABLED");
                setOffMessage();
                break;
        }

        mLastInfo = null;
        mLastState = null;
        mScanner.pause();
    }

    private class Scanner extends Handler {
        private int mRetry = 0;

        void resume() {
            if (!hasMessages(0))
                sendEmptyMessage(0);
        }

        void forceScan() {
            removeMessages(0);
            sendEmptyMessage(0);
        }

        void pause() {
            mRetry = 0;
            removeMessages(0);
        }

        @Override
        public void handleMessage(Message message) {
            if (mWifiManager.startScan()) {
                mRetry = 0;
            } else if (++mRetry >= 3) {
                mRetry = 0;
                Activity activity = getActivity();
                if (activity != null)
                    Toast.makeText(activity, R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show();
                return;
            }
            sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);
        }
    }

    /**
     * Renames/replaces "Next" button when appropriate. "Next" button usually exists in
     * Wifi setup screens, not in usual wifi settings screen.
     *
     * @param connected true when the device is connected to a wifi network.
     */
    private void changeNextButtonState(boolean connected) {
        if (mEnableNextOnConnection) {
            //getNextButton().setEnabled(connected);
        }
    }

    @Override
    public void onClick(DialogInterface dialogInterface, int button) {
    	Logger.d(TAG, "ONCLICK");
        if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {
            forget();
        } else if (button == WifiDialog.BUTTON_SUBMIT) {
            if (mDialog == null)
            		return;
            submit(mDialog.getController(), null);
        }
    }
    
    public void connectApByNetWorkId() {
    		try {
			Method connect = mWifiManager.getClass().getMethod("connect", int.class, getActionLisenerClass());
			connect.invoke(mWifiManager, mSelectedAccessPoint.networkId, null);
    		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}   
    }
    
	private Class getActionLisenerClass()
    {
       	Class c = null;
		try {
			c = Class.forName("android.net.wifi.WifiManager$ActionListener");
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		return c; 	
    }
	
	private List<WifiConfiguration> getListCofigurations(){
		if(mWifiManager == null)
			return null;
		
		return mWifiManager.getConfiguredNetworks(); 
	}
    
    public void connectApByConfig(WifiConfiguration config) {
    		try {
			Method connect = mWifiManager.getClass().getMethod("connect", WifiConfiguration.class, getActionLisenerClass());
			connect.invoke(mWifiManager, config, null);
    		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}   
    }
    
    public void saveApByConfig(WifiConfiguration config, Object mSaveListener) {
    		try {
			Method save = mWifiManager.getClass().getMethod("save", WifiConfiguration.class, getActionLisenerClass());
			save.invoke(mWifiManager, config, null);
    		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}    	
    }
    
    /* package */ 
    void submit(WifiConfigController configController, Object mSaveListener)  {
        final WifiConfiguration config = configController.getConfig();
        //for hide
        Logger.d(TAG, "submit");
      	if (config == null) {
      		Logger.d(TAG, "config is null");
            if (mSelectedAccessPoint != null && 
            		mSelectedAccessPoint.networkId != ReflectionUtil.INVALID_NETWORK_ID) {
            		connectApByNetWorkId();
            }
        } else if (config.networkId != ReflectionUtil.INVALID_NETWORK_ID) {
            if (mSelectedAccessPoint != null)
            		saveApByConfig(config, mSaveListener);
        } else {
        		Logger.d(TAG, "config is not null");
            if (configController.isEdit()) {
            		Logger.d(TAG, "saveApByConfig");
            		saveApByConfig(config, mSaveListener);
            } else {
            		Logger.d(TAG, "connectApByConfig");
            		connectApByConfig(config);
            }
        }

        if (mWifiManager.isWifiEnabled())
            mScanner.resume();
        
        updateAccessPoints();
    }
    
    void submit(Object mSaveListener,String password,boolean isEdit) {
    		try {
    			final WifiConfiguration config = WifiConfigController.getConfig(mSelectedAccessPoint,password,isEdit);
	        //for hide
	        Logger.d(TAG, "submit");
	      	if (config == null) {
	      		Logger.d(TAG, "config is null");
	            if (mSelectedAccessPoint != null && 
	            		mSelectedAccessPoint.networkId != ReflectionUtil.INVALID_NETWORK_ID) {
	            		connectApByNetWorkId();
	            }
	        } else if (config.networkId != ReflectionUtil.INVALID_NETWORK_ID) {
	            if (mSelectedAccessPoint != null)
	            		saveApByConfig(config, mSaveListener);
	        } else {
	        		Logger.d(TAG, "config is not null");
	            if (isEdit) {
	            		Logger.d(TAG, "saveApByConfig");
	            		saveApByConfig(config, mSaveListener);
	            } else {
	            		Logger.d(TAG, "connectApByConfig");
	            		connectApByConfig(config);
	            }
	        }
	
	        if (mWifiManager.isWifiEnabled())
	            mScanner.resume();
	        
	        updateAccessPoints();
    	} catch (Exception e) {
			// TODO: handle exception
		}
    }

    public void forgetApByNetworkId(int networkid, Object mForgetListener) {
    		try {
			Method forget = mWifiManager.getClass().getMethod("forget", int.class, getActionLisenerClass());
			forget.invoke(mWifiManager, networkid, null);
    		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}    	
    }   
    
    /* package */ 
    	void forget() {
    		//for hide
       if (mSelectedAccessPoint.networkId == ReflectionUtil.INVALID_NETWORK_ID) {
            // Should not happen, but a monkey seems to triger it
            Logger.e(TAG, "Failed to forget invalid network " + mSelectedAccessPoint.getConfig());
            return;
        }
       
        forgetApByNetworkId(mSelectedAccessPoint.networkId, null);
      
        if (mWifiManager.isWifiEnabled())
            mScanner.resume();

        updateAccessPoints();

        // We need to rename/replace "Next" button in wifi setup context.
        changeNextButtonState(false);
    }

    /**
     * Refreshes acccess points and ask Wifi module to scan networks again.
     */
    /* package */ 
    	void refreshAccessPoints() {
        if (!mWifiManager.isWifiEnabled())
        		return;
        mScanner.resume();
    }

    /**
     * Called when "add network" button is pressed.
     */
    /* package */ 
    	void onAddNetworkPressed() {
        // No exact access point is selected.
        mSelectedAccessPoint = null;
        showDialog(null, true);
    }

    /* package */ 
    	int getAccessPointsCount() {
        final boolean wifiIsEnabled = mWifiManager.isWifiEnabled();
        if (wifiIsEnabled)
            return mLstViewWifi.getCount();
        else
            return 0;
    }

    /**
     * Requests wifi module to pause wifi scan. May be ignored when the module is disabled.
     */
    /* package */ 
    	void pauseWifiScan() {
        if (!mWifiManager.isWifiEnabled()) 
        		return;
        mScanner.pause();
    }

    /**
     * Requests wifi module to resume wifi scan. May be ignored when the module is disabled.
     */
    /* package */ void resumeWifiScan() {
        if (!mWifiManager.isWifiEnabled()) 
        		return;
        mScanner.resume();
    }
    
    /**
     * Used as the outer frame of all setup wizard pages that need to adjust their margins based
     * on the total size of the available display. (e.g. side margins set to 10% of total width.)
     */
    public static class ProportionalOuterFrame extends RelativeLayout {
        public ProportionalOuterFrame(Context context) {
            super(context);
        }
        
        public ProportionalOuterFrame(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
        
        public ProportionalOuterFrame(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        /**
         * Set our margins and title area height proportionally to the available display size
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
            final Resources resources = getContext().getResources();
            float sideMargin = resources.getFraction(R.dimen.setup_border_width, 1, 1);
            int bottom = resources.getDimensionPixelSize(R.dimen.setup_margin_bottom);
            setPaddingRelative((int)(parentWidth * sideMargin), 0, (int) (parentWidth * sideMargin), bottom);
            
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    
    class WifiItemAdapter extends BaseAdapter {
    		private LayoutInflater inflater;
    		private List<AccessPoint> list;
    		private WifiInfo mCurentLastInfo;
    		private String mCurrentSSID;
    		
    		public WifiItemAdapter(Context context) {
    			inflater = LayoutInflater.from(context);
		}
    	
    		public void setWifiListData(List<AccessPoint> datas) {
	    		list = datas;
	    		mCurentLastInfo = mWifiManager.getConnectionInfo();
	    		mCurrentSSID = mCurentLastInfo.getSSID();
	    		mCurrentSSID = mCurrentSSID.substring(1, mCurrentSSID.length()-1);
	    	}

		@Override
		public int getCount() {
			if(list == null)
				return 0;
			
			return list.size();
		}

		@Override
		public Object getItem(int position) {
			if(list == null)
				return null;
			
			return list.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder viewHolder;
			final AccessPoint accessPoint = list.get(position);
			if(convertView == null) {
				convertView = inflater.inflate(R.layout.wifi_setting_item, parent, false);
				viewHolder = new ViewHolder();
				viewHolder.signalWifiImg = (ImageView)convertView.findViewById(R.id.wifi_item_signal_img);
				viewHolder.wifiName = (TextView)convertView.findViewById(R.id.wifi_item_name_txt);
				viewHolder.wifiDirectImg = (ImageView)convertView.findViewById(R.id.wifi_item_direct_img);
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder)convertView.getTag();
			}
			
			viewHolder.signalWifiImg.setImageLevel(accessPoint.getLevel());
			viewHolder.wifiName.setText(accessPoint.getTitle());
			if(accessPoint.getState() == DetailedState.CONNECTED || 
			   accessPoint.ssid.equals(mCurrentSSID))
				viewHolder.wifiName.setTextColor(getResources().getColor(R.color.wifi_connect_netname_color));
			else
				viewHolder.wifiName.setTextColor(getResources().getColor(R.color.wifi_connect_txt_color));
			
			return convertView;
		}
		
		public class ViewHolder {
			ImageView signalWifiImg;
			TextView wifiName;
			ImageView wifiDirectImg;
		}
    }

	@Override
	public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
		mSelectedAccessPoint  = (AccessPoint)adapter.getItemAtPosition(position);
		
		
	    if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
                mSelectedAccessPoint.networkId == ReflectionUtil.INVALID_NETWORK_ID){
	    	
	    	 mSelectedAccessPoint.generateOpenNetworkConfig();//连接无密码
	 	     connectApByConfig(mSelectedAccessPoint.getConfig());
	    }else{
			Logger.i(TAG, "currentPoint.ssid is:"+mSelectedAccessPoint.ssid);
			String ssid = mWifiManager.getConnectionInfo().getSSID();
			ssid = ssid.substring(1, ssid.length()-1);
			
			Bundle bundle = new Bundle();
		    bundle.putString("wifi_name", mSelectedAccessPoint.getTitle().toString());
		    bundle.putInt("wifi_signal",mSelectedAccessPoint.getLevel());
		    bundle.putString("wifi_security", mSelectedAccessPoint.getSecurityString(true));
	//----------------------------------------------------------------------------------------------------

		   
	 
			if (mSelectedAccessPoint.getState() == null &&
	            mSelectedAccessPoint.networkId != ReflectionUtil.INVALID_NETWORK_ID) {
	            Logger.d(TAG, "connectApByConfig ");
	            bundle.putInt("show_type", ConnectImpl.SHOWTYPE_OLD);
	        } else if(mSelectedAccessPoint.getState() != null || 
	        		mSelectedAccessPoint.getState() == DetailedState.CONNECTED) {
			    bundle.putInt("show_type", ConnectImpl.SHOWTYPE_CONNECTED);
	        } else {
	        		bundle.putInt("show_type", ConnectImpl.SHOWTYPE_NORMAL);
	        }
			
			connectImpl.connectNetItem(bundle);
	    }
	    

	}
	
	private void onWifiItemClick(AccessPoint preference){
		if (!(preference instanceof AccessPoint)) 
			return;
		
        mSelectedAccessPoint = (AccessPoint) preference;
        /** Bypass dialog for unsecured, unsaved networks */
        //for hide
        if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
            mSelectedAccessPoint.networkId == ReflectionUtil.INVALID_NETWORK_ID) {
            mSelectedAccessPoint.generateOpenNetworkConfig();
            Logger.d(TAG, "connectApByConfig ");
            connectApByConfig();
        } else {
        		Logger.d(TAG, "show dialog");
            showDialog(mSelectedAccessPoint, false);
        } 
	}

	@Override
	public void onClick(View v) {
		if(v == mTxtViewScanner) {
			Logger.d(TAG,"scannerTxt click");
			dialog.setMessage("搜索中...");  
			dialog.setCancelable(false); 
			dialog.show();
	        
			//handler.sendEmptyMessageDelayed(9001, 2000);
			IS_SCAN_CLICK=true;
			mWifis.clear();
        		mWifiItemAdapter.notifyDataSetInvalidated();
			refreshAccessPoints();
		}else if(v == mImgViewExit) {
			connectImpl.exit(ConnectImpl.LIST);
		}
	}
	
	Handler handler = new Handler(){
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case 9001:
				dialog.dismiss();
				break;
			case 9002:
				if (dialog != null && dialog.isShowing()) {
					dialog.dismiss();
					//forget();//add for test
					/*dialog.setMessage("刷新wifi");  
					dialog.setCancelable(false); 
					dialog.show();
					IS_SCAN_CLICK=true;
					mWifis.clear();
		        		mWifiItemAdapter.notifyDataSetInvalidated();
					refreshAccessPoints();*/
					Toast.makeText(mActivity, "WIFI连接异常", Toast.LENGTH_LONG).show();
				}
				break;
			default:
				break;
			}
		};
	};
	
	/**
	 * 连接wifi
	 * pwd 为输入密码
	 */
	public void connectAp(String pwd){
		Logger.d(TAG, "input pwd is:"+pwd);
		int mCurrentSSID = mWifiManager.getConnectionInfo().getNetworkId();
		if(!TextUtils.isEmpty(mCurrentSSID + ""))
			mWifiManager.disableNetwork(mCurrentSSID);
		submit(null, pwd, true);
		if(dialog == null)
    			dialog = WaitDialog.createDialog(mActivity);

		if(!dialog.isShowing()){
			dialog.setMessage("正在连接WiFi");	
			dialog.show();	
		}
		
		handler.sendEmptyMessageDelayed(9002, 10000);
	}
	
	/**
	 * 连接已经记住密码的wifi
	 */
	public void reconnectAp(){
		mWifiManager.enableNetwork(mSelectedAccessPoint.networkId, true);
		if(dialog == null)
    			dialog = WaitDialog.createDialog(mActivity);

		if(!dialog.isShowing()) {
			dialog.setMessage("正在连接WiFi");	
    			dialog.show();	
		}
	
		handler.sendEmptyMessageDelayed(9002, 10000);
	}
	
	public void forgetAp(){
		forget();
	}
	
	public void connectByConfig(){
		connectApByConfig();
	}
}
